/* Copyright (c) 2004-2024 Peigen.info. All rights reserved. */

package info.peigen.hotpot.demo.scheduler.service.task;

import com.alibaba.fastjson2.JSON;
import info.peigen.hotpot.demo.scheduler.domain.Task;
import info.peigen.hotpot.demo.scheduler.domain.Trade;
import info.peigen.hotpot.demo.scheduler.service.step.base.TaskContext;
import info.peigen.hotpot.demo.scheduler.service.step.base.TaskProcessor;
import info.peigen.hotpot.demo.scheduler.service.task.processor.ChargeReadyProcessor;
import info.peigen.hotpot.demo.scheduler.service.task.processor.RobotBackProcessor;
import info.peigen.hotpot.demo.scheduler.service.task.processor.SendStubTaskProcessor;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.noear.solon.annotation.Component;
import org.noear.solon.annotation.Inject;
import org.noear.solon.core.event.EventBus;

import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.CompletableFuture;

/**
 * <b>(TaskService)</b>
 *
 * @author Lihai
 * @version 1.0.0
 * @since 2023/9/10
 */
@Slf4j
@Component
@Data
public class TaskService {
    @Inject
    SendStubTaskProcessor sendStubTaskProcessor;
    @Inject
    RobotBackProcessor    robotBackProcessor;
    @Inject
    ChargeReadyProcessor  chargeReadyProcessor;

    Map<String, Task> taskIdMap   = new HashMap<>();
    Map<String, Task> taskNameMap = new HashMap<>();

    public void initTask(Trade trade) {
        Task task = sendStubTaskProcessor.buildTask(trade);
        taskIdMap.put(task.getTaskId(), task);
        taskNameMap.put(task.getName(), task);
        log.info("store task: {}", JSON.toJSONString(task));

        Task task2 = robotBackProcessor.buildTask(trade);
        taskIdMap.put(task2.getTaskId(), task2);
        taskNameMap.put(task2.getName(), task2);
        log.info("store task: {}", JSON.toJSONString(task2));

        Task task3 = chargeReadyProcessor.buildTask(trade);
        taskIdMap.put(task3.getTaskId(), task3);
        taskNameMap.put(task3.getName(), task3);
        log.info("store task: {}", JSON.toJSONString(task3));

        // 订阅
        EventBus.subscribe(sendStubTaskProcessor.triggerEvent(), event -> {
            this.execute(task);
        });
        EventBus.subscribe(robotBackProcessor.triggerEvent(), event -> {
            CompletableFuture.runAsync(() -> {
                this.execute(task2);
            });
            CompletableFuture.runAsync(() -> {
                this.execute(task3);
            });
        });
    }

    public void execute(Task task) {
        TaskProcessor taskProcessor = task.getTaskProcessor();
        taskProcessor.executeNextStep(new TaskContext().setTask(task));
    }
}
